package com.tianji.promotion.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tianji.common.domain.dto.PageDTO;
import com.tianji.promotion.domain.po.Coupon;
import com.tianji.promotion.domain.po.ExchangeCode;
import com.tianji.promotion.domain.query.CodeQuery;
import com.tianji.promotion.mapper.ExchangeCodeMapper;
import com.tianji.promotion.service.IExchangeCodeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tianji.promotion.utils.CodeUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.tianji.common.constants.Constant.EXCHANGE_CODE;

/**
 * <p>
 * 兑换码 服务实现类
 * </p>
 *
 * @author WFan
 * @since 2025-04-03
 */
@Service
@RequiredArgsConstructor
public class ExchangeCodeServiceImpl extends ServiceImpl<ExchangeCodeMapper, ExchangeCode> implements IExchangeCodeService {
    private final RedisTemplate redisTemplate;


    /**
     * 兑换码分页查询
     *
     * @param query
     * @return
     */
    @Override
    public PageDTO<?> codePageQuery(CodeQuery query) {
        // 1.查询兑换码
        Page<ExchangeCode> page = this.lambdaQuery().eq(ExchangeCode::getExchangeTargetId, query.getCouponId())
                .eq(ExchangeCode::getStatus, query.getStatus())
                .page(query.toMpPageDefaultSortByCreateTimeDesc());
        List<ExchangeCode> records = page.getRecords();
        if (ObjectUtil.isEmpty(records)){
            return PageDTO.empty(page);
        }

        List<Map<String,Object>> list = records.stream().map(r -> {
            Map<String,Object> map = new HashMap<>(2);
            map.put("id", r.getId());
            map.put("code", r.getCode());
            return map;
        }).collect(Collectors.toList());
        return PageDTO.of(page, list);
    }

    /**
     * 生成兑换码
     *
     * @param coupon
     */
    @Override
    @Async("generateExchangeCodeExecutor")
    public void asyncGenerateCode(Coupon coupon) {
        // 4.1获取优惠券总数
        Integer totalNum = coupon.getTotalNum();
        BoundValueOperations boundValueOperations = redisTemplate.boundValueOps(EXCHANGE_CODE);
        Long result = boundValueOperations.increment(totalNum);
        if (result == null){
            return;
        }
        int codeId = result.intValue();
        List<ExchangeCode> exchangeCodeList = new ArrayList<>(totalNum);

        // 4.2.生成优惠券码
        for (int i = codeId - totalNum; i <= codeId; i++) {
            String code = CodeUtil.generateCode(i, coupon.getId());
            ExchangeCode exchangeCode = new ExchangeCode().setCode(code)
                    .setType(1)
                    .setExchangeTargetId(coupon.getId())
                    .setCreateTime(LocalDateTime.now());
            exchangeCodeList.add(exchangeCode);
        }

        // 4.3.保存优惠券码
        this.saveBatch(exchangeCodeList);
    }
}
